from typing import List

from sqlalchemy import String, Text, SmallInteger, Boolean, ForeignKey, Integer, DateTime
from sqlalchemy.orm import mapped_column, Mapped, relationship
from .common import add_serializer, YgBase, int_pk_auto


@add_serializer
class SysJsonSettings(YgBase):
    __tablename__: str = "sys_json_settings"
    id: Mapped[int_pk_auto]
    type: Mapped[str] = mapped_column(String(500), nullable=False)
    key: Mapped[str] = mapped_column(String(500), nullable=False)
    value: Mapped[str] = mapped_column(Text, nullable=False)

    def __repr__(self) -> str:
        return f'name: setting of {self.key}'
    def __str__(self) -> str:
        return f'name: setting of {self.key}'


@add_serializer
class SysCustomReportConfig(YgBase):
    __tablename__: str = "sys_customReportConfig"
    id: Mapped[int_pk_auto]
    name: Mapped[str] = mapped_column(String(250))
    code: Mapped[str] = mapped_column(String(100))
    sql: Mapped[Text] = mapped_column(Text, nullable=False)
    memo: Mapped[str] = mapped_column(String(2000), nullable=True)
    type: Mapped[str] = mapped_column(String(50))
    primary_key: Mapped[str] = mapped_column(String(255), nullable=True)
    hierarchy_field: Mapped[str] = mapped_column(String(255), nullable=True)
    report_type: Mapped[str] = mapped_column(String(255))
    dimensions: Mapped[str] = mapped_column(String(255), nullable=True)
    nodes: Mapped[str] = mapped_column(String(255), nullable=True)
    indexes: Mapped[str] = mapped_column(String(255), nullable=True)
    main_table: Mapped[str] = mapped_column(String(255), nullable=True)
    query_param_no_per_line: Mapped[int] = mapped_column(SmallInteger,default=3, nullable=True)
    form_item_no_per_line: Mapped[int] = mapped_column(SmallInteger,default=3, nullable=True)
    width_type: Mapped[int] = mapped_column(SmallInteger,default=0, nullable=True)
    exportable: Mapped[bool] = mapped_column(Boolean,default=False, nullable=True)
    printable: Mapped[bool] = mapped_column(Boolean,default=False, nullable=True)
    editable: Mapped[bool] = mapped_column(Boolean,default=False, nullable=True)
    deletable: Mapped[bool] = mapped_column(Boolean,default=False, nullable=True)
    batch_deletable: Mapped[bool] = mapped_column(Boolean,default=False, nullable=True)
    # 一对多关系：一个报表配置对应多个报表参数
    report_params: Mapped[List["SysCustomReportParams"]] = relationship(back_populates="report_config", cascade="all, delete-orphan")

    def __repr__(self) -> str:
        return f'name: {self.name}'
    def __str__(self) -> str:
        return f'name: {self.name}'


@add_serializer
class SysCustomReportParams(YgBase):
    __tablename__: str = "sys_customReportParams"
    id: Mapped[int_pk_auto]
    conf_id: Mapped[int] = mapped_column(ForeignKey("sys_customReportConfig.id"), nullable=False)
    field_name: Mapped[str] = mapped_column(String(255), nullable=False)
    field_txt: Mapped[str] = mapped_column(String(255), nullable=False)
    field_width: Mapped[int] = mapped_column(Integer, nullable=True)
    field_type: Mapped[str] = mapped_column(String(50), nullable=False)
    field_align: Mapped[str] = mapped_column(String(20), nullable=True)
    field_href: Mapped[str] = mapped_column(String(255), nullable=True)
    is_show: Mapped[bool] = mapped_column(Boolean, default=True)
    is_search: Mapped[bool] = mapped_column(Boolean, default=False)
    param_order: Mapped[int] = mapped_column(SmallInteger, nullable=True)
    sortable: Mapped[bool] = mapped_column(Boolean, default=False)
    editable: Mapped[bool] = mapped_column(Boolean, default=False)
    is_required: Mapped[int] = mapped_column(SmallInteger, default=False)
    search_mode: Mapped[str] = mapped_column(String(50), nullable=True)
    dict_code: Mapped[str] = mapped_column(String(100), nullable=True)
    # 反向引用报表配置
    report_config: Mapped["SysCustomReportConfig"] = relationship(back_populates="report_params")

    def __repr__(self) -> str:
        return f'param: {self.field_name}'

    def __str__(self) -> str:
        return f'param: {self.field_name}'